package com.cap.bts.crmdp.webservice.dc;

import java.io.File;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.cap.bts.crmdp.dealer.dealerinfosync.util.ProcessCsvFileUtils;
import com.cap.bts.crmdp.dealer.mars.domain.DataConversionLog;
import com.cap.bts.crmdp.dealer.mars.service.IDataConversionLogService;
import com.cap.bts.crmdp.dealer.masterdata.dto.DataConvertStoredProcedure;
import com.cap.bts.crmdp.dealer.masterdata.dto.MarsDataConversionMemberDto;
import com.cap.bts.crmdp.dealer.masterdata.dto.MarsDataConversionPortfolioDto;
import com.cap.bts.crmdp.dealer.masterdata.service.IMaintainDealerService;
import com.cap.bts.crmdp.webservice.dto.DtCrmDto;
import com.cap.bts.framework.codemapping.service.ICodeMapping;
import com.cap.bts.framework.common.exception.AppException;
import com.cap.bts.framework.common.util.ApplicationContextUtil;

public class DataConversionProcess {
	private static final Logger LOGGER = Logger.getLogger(DataConversionProcess.class);
	private DtCrmDto dto;
	private int currentRetry = 0;
	private int maxRetry = 10;
	private DataConversionLog marsLog;

	public DataConversionProcess(DtCrmDto dto) {
		this.marsLog = DataConversionQueue.getBatchInitDate(dto.getBatchId());
		this.dto = dto;
	}


	public void process() {
		String errorCode = "";
		String errorMessage= "";		
		
		marsLog.setStatus("2");	
		
		StringBuilder message = new StringBuilder();
		message.append("\nbatchId:").append(dto.getBatchId());
		message.append("\nDealerNumber:").append(dto.getDealerNumber());
		message.append("\ncustVehicleFile:").append(dto.getCustVehicleFile());
		message.append("\ncustVehicleCount:").append(dto.getCustVehicleCount());
		message.append("\nportfolioFile:").append(dto.getPortfolioFile());
		message.append("\nportfolioCount:").append(dto.getPortfolioCount());
		message.append("\ndescp:").append(dto.getDescp());
		
		marsLog.setParamText(message.toString());
		
		LOGGER.info(message.toString());
		
		//必要数据校验
		if(StringUtils.isBlank(dto.getCustVehicleFile()) && StringUtils.isBlank(dto.getPortfolioFile())){
			LOGGER.error("缺失文件路径参数");
			errorCode = "E23";
			errorMessage = "缺失文件路径参数";

			callDC("false", errorCode, errorMessage, "", "");
			return;
		}
		
		
		//获取临时目录
		ICodeMapping codeMappingService = (ICodeMapping) ApplicationContextUtil.getBean("codeMappingImpl");
		String tmpPath = "";
		try {
			tmpPath = codeMappingService.getCodeValueByCode("tmpPath", "tmpPath");
			
		} catch (AppException e1) {
			LOGGER.error("", e1);
			errorCode = "EEE";
			errorMessage = "系统配置error";

			callDC("false", errorCode, errorMessage, "", "");
			return;
		}
		
		
		IMaintainDealerService maintainDealerServiceimpl = (IMaintainDealerService) ApplicationContextUtil
				.getBean("maintainDealerServiceimpl");
        
      //下载文件
        String memberFilePath = dto.getCustVehicleFile();
        List<MarsDataConversionMemberDto> memberDtoList  =  null;
        if(StringUtils.isNotBlank(memberFilePath)){
        	int memberSplit = memberFilePath.lastIndexOf("/") + 1;
            String tmpMemberFilePath = tmpPath + dto.getBatchId() + "_" + memberFilePath.substring(memberSplit);
            
            try {
    			maintainDealerServiceimpl.downLodeMemberFile(memberFilePath.substring(memberSplit), memberFilePath.substring(0, memberSplit - 1), tmpMemberFilePath);


//    			System.out.println("downLodeMemberFile: " + flag);
    		} catch (Exception e) {
    			LOGGER.error("", e);
    			errorCode = "E23";
    			errorMessage = "文件下载错误";

    			callDC("false", errorCode, errorMessage, "", "");
    			return;
    		}
            
            
            
          //解析文件
            
            try{
            	memberDtoList  = ProcessCsvFileUtils.combinationMemberList(ProcessCsvFileUtils.analyzeCsv(new File(tmpMemberFilePath)));
            }catch(Exception e){
            	LOGGER.error("", e);
    			errorCode = "E24";
    			errorMessage = "文件格式错误，解析失败";

    			callDC("false", errorCode, errorMessage, "", "");
    			return;
            }
            
//            System.out.println(memberDtoList.size());
            
            
          //校验文件数量和传递数量是否一致，不一致，直接返回，不再调用存储过程
    		if (!dto.getCustVehicleCount().equals(memberDtoList.size())) {
    			errorCode = "E20";
    			errorMessage = "CustVehicle数量不一致";

    			callDC("false", errorCode, errorMessage, "", "");
    			return;
    		}
        }
        
        
        
        
        String portfolioFilePath = dto.getPortfolioFile();
    	List<MarsDataConversionPortfolioDto> portfolioDtoList = null;
        if(StringUtils.isNotBlank(memberFilePath)){
        
        	int portfolioSplit = portfolioFilePath.lastIndexOf("/") + 1;
        	String tmpPortfolioFilePath = tmpPath +  dto.getBatchId() + "_" + portfolioFilePath.substring(portfolioSplit);
        	try {
        		maintainDealerServiceimpl.downLodeProtfolioFile(portfolioFilePath.substring(portfolioSplit), portfolioFilePath.substring(0, portfolioSplit - 1), tmpPortfolioFilePath);
        	} catch (Exception e) {
        		LOGGER.error("", e);
        		errorCode = "E23";
        		errorMessage = "文件下载错误";
        		
        		callDC("false", errorCode, errorMessage, "", "");
        		return;
        		
        	}
        	
        	//解析文件
        	try {
        		portfolioDtoList = ProcessCsvFileUtils.combinationProtfolioList(ProcessCsvFileUtils.analyzeCsv(new File(tmpPortfolioFilePath)));
        	} catch (Exception e) {
        		LOGGER.error("", e);
        		errorCode = "E24";
        		errorMessage = "文件格式错误，解析失败";
        		
        		callDC("false", errorCode, errorMessage, "", "");
        		return;
        	}
        	
//        	System.out.println(portfolioDtoList.size());
        	//校验文件数量和传递数量是否一致，不一致，直接返回，不再调用存储过程
    		if (!dto.getPortfolioCount().equals(portfolioDtoList.size())) {
    			errorCode = "E21";
    			errorMessage = "Portfolio数量不一致";
    			callDC("false", errorCode, errorMessage, "", "");
    			return;
    		}
        }
        
        
       //存储文件数据到数据库
        boolean existHistoryDataFlag = maintainDealerServiceimpl.checkExistHistoryData(dto.getDealerNumber(), StringUtils.isNotBlank(memberFilePath), StringUtils.isNotBlank(portfolioFilePath));
        if(existHistoryDataFlag){
       	 //存在数据，上次未处理完
        	errorCode = "E03";
			errorMessage = "Another data conversion process of dealer " + dto.getDealerNumber() + " is still in progress.";
			callDC("false", errorCode, errorMessage, "", "");
			return;
       	 
        }
        
        maintainDealerServiceimpl.insertDTData(dto.getBatchId(), memberDtoList, portfolioDtoList);
        
       //然后调用存储过程
        LOGGER.info("call prc " + dto.getBatchId());
        DataConvertStoredProcedure dataConvertResult = maintainDealerServiceimpl.callPrcDataConversion(dto.getDealerNumber(), StringUtils.isNotBlank(memberFilePath), StringUtils.isNotBlank(portfolioFilePath));
        
        if(StringUtils.isNotBlank(dataConvertResult.getReturnCode()) && StringUtils.startsWith(dataConvertResult.getReturnCode(), "E")){//转换出错
        	errorCode = dataConvertResult.getReturnCode();
			errorMessage = dataConvertResult.getErrorMessage();
			String memberFileName = "";
			String portfolioFile = "";
			
			if("E10".equals(errorCode)){//生成文件并上传
				try {
					memberFileName = maintainDealerServiceimpl.upLodeMemberFile(dto.getDealerNumber());
					portfolioFile = maintainDealerServiceimpl.upLodePortfolioFile(dto.getDealerNumber());
				} catch (Exception e) {
					LOGGER.error("", e);
				}
			}
			
			callDC("false", errorCode, errorMessage, memberFileName, portfolioFile);
        }else{
        	callDC("true", errorCode, errorMessage, "", "");
        }
        
        
	}
	
	
	private boolean callDC(String successFlag, String errorCode, String errorMessage,String crmFileName, String portfolioFileName){
	    marsLog.setStatus("true".equals(successFlag) ? "3" : "4");
		//通知hand 处理结果
       URL url;
		try {
			DCProperties dcProperties;
			ICodeMapping codeMappingService = (ICodeMapping) ApplicationContextUtil.getBean("codeMappingImpl");
			
			String dcInfo = codeMappingService.getCodeValueByCode("DataConvertInfo", "DataConvertServerInfo");
			if(StringUtils.isNotBlank(dcInfo)){
				dcProperties = JSON.parseObject(dcInfo, DCProperties.class);
			}else{
				throw new AppException("ERROR", "DataConvertInfo 服务器未配置.");
			}
			
			
			url = new URL(dcProperties.getHost());
		
   	
	 		HttpURLConnection uc = (HttpURLConnection) url.openConnection();
	 		
	 		uc.setConnectTimeout(60000);
	 		
	 		uc.setReadTimeout(30000);
	
	 		uc.setDoInput(true);
	 		
	 		uc.setDoOutput(true);
	 		
	 		uc.setRequestMethod("POST");
	 		
	 		uc.addRequestProperty("username", dcProperties.getUserName());
	 		
	 		uc.addRequestProperty("password", dcProperties.getPassword());
	 		
	 		StringBuilder msg = new StringBuilder();
	 		msg.append("isSuccess=").append(successFlag);
	 		msg.append("&batch_id=").append(dto.getBatchId());
	 		msg.append("&errorCode=").append(errorCode);
	 		msg.append("&errorMessage=").append(URLEncoder.encode(errorMessage,"UTF-8"));
	 		msg.append("&crmFilename=").append(URLEncoder.encode(StringUtils.defaultString(crmFileName),"UTF-8"));
	 		msg.append("&portfolioFileName=").append(URLEncoder.encode(StringUtils.defaultString(portfolioFileName),"UTF-8"));
	 		
	 		LOGGER.info("call DC: " + msg.toString());
	 		
	 		marsLog.setSendText(msg.toString());
	 		
	 		uc.getOutputStream().write(msg.toString().getBytes());
//	 		uc.getOutputStream().write(("isSuccess=true&crmFilename=" + URLEncoder.encode("/error/20151130.csv","UTF-8") + "&type=xxx&batch_id=20151129001").getBytes());
	 		
	 		uc.connect();
	 		InputStream inStream= uc.getInputStream();
	 		String returnText = new String(IOUtils.toString(inStream, "UTF-8"));
	 		LOGGER.error("DC return:" +  returnText);
	 		marsLog.setReturnText(returnText);
	 		
	 		IDataConversionLogService dataConversionLogServiceImpl = (IDataConversionLogService) ApplicationContextUtil.getBean("dataConversionLogServiceImpl");
	 		
	 		dataConversionLogServiceImpl.update(marsLog);
//	 		ThreadPoolUtil.execute(new LogTask(marsLog));
	 		
	 		return true;
		} catch (Exception e) {
			LOGGER.error("", e);
			marsLog.setDescp(e.getMessage());
			currentRetry ++ ;
			if(currentRetry <= maxRetry){
				callDC(successFlag, errorCode, errorMessage, crmFileName, portfolioFileName);
			}else{
				
				IDataConversionLogService dataConversionLogServiceImpl = (IDataConversionLogService) ApplicationContextUtil.getBean("dataConversionLogServiceImpl");
		 		
		 		dataConversionLogServiceImpl.update(marsLog);
				
//				ThreadPoolUtil.execute(new LogTask(marsLog));
			}
		}
		
		return false;
   }
	
}
